/*
 * echoserveri.c - An iterative echo server
 */
/* $begin echoserverimain */

#include "csapp.h"

void echo(int connfd);

void command(void);

int main(int argc, char **argv)
{
    int listenfd, connfd, port, clientlen = sizeof(struct sockaddr_in);
    struct sockaddr_in clientaddr;
    struct hostent *hp;
    char *haddrp;
    fd_set read_set,ready_set;
    if (argc != 2)
	{
		fprintf(stderr, "usage: %s <port>\n", argv[0]);
		exit(0);
    }
    port = atoi(argv[1]);
    listenfd = Open_listenfd(port);

    FD_ZERO(&read_set);
    FD_SET(STDIN_FILENO, &read_set);
    FD_SET(listenfd, &read_set);
    while (1)
	{
	    ready_set=read_set;//重新载入
	    Select(listenfd+1, &ready_set, NULL, NULL, NULL); //挂起进程

	    if(FD_ISSET(STDIN_FILENO, &ready_set))
	    {
	        printf("server connected to local stdin.\n");
	        command();
	    }
	    if(FD_ISSET(listenfd, &ready_set))
	    {
            connfd = Accept(listenfd, (SA *)&clientaddr, &clientlen);
            hp = Gethostbyaddr((const char *)&clientaddr.sin_addr.s_addr,
            sizeof(clientaddr.sin_addr.s_addr), AF_INET);
            haddrp = inet_ntoa(clientaddr.sin_addr);
            printf("server connected to %s (%s)\n", hp->h_name, haddrp);
            echo(connfd);
            Close(connfd);
	    }
    }
    exit(0);
}

void command(void)
{
    char buf[MAXLINE];
    if (!Fgets(buf, MAXLINE, stdin))
        exit(0);
    printf("%s", buf);
}


void echo(int connfd) 
{
    size_t n; 
    char buf[MAXLINE]; 
    rio_t rio;

    Rio_readinitb(&rio, connfd);
    while((n = Rio_readlineb(&rio, buf, MAXLINE)) != 0) 
	{ //line:netp:echo:eof
		printf("server received %d bytes\n", n);
		Rio_writen(connfd, buf, n);
    }
}


